home *** CD-ROM | disk | FTP | other *** search
/ Aminet 49 / Aminet 49 (2002)(GTI - Schatztruhe)[!][Jun 2002].iso / Aminet / util / sys / AmberRAM.lha / AmberRAM / Source / commands.c next >
C/C++ Source or Header  |  2002-02-27  |  41KB  |  2,361 lines

  1. /*
  2.  
  3. File: commands.c
  4. Author: Neil Cafferkey
  5. Copyright (C) 2001-2002 Neil Cafferkey
  6.  
  7. This program is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU General Public License
  9. as published by the Free Software Foundation; either version 2
  10. of the License, or (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  20. MA 02111-1307, USA.
  21.  
  22. */
  23.  
  24.  
  25. #include "handler_protos.h"
  26.  
  27.  
  28. const TEXT utility_name[]=UTILITYNAME;
  29. const TEXT locale_name[]="locale.library";
  30. const TEXT default_vol_name[]="Ram Disc";
  31.  
  32.  
  33.  
  34. /****i* ram.handler/CmdStartup *********************************************
  35. *
  36. *   NAME
  37. *    CmdStartup --
  38. *
  39. *   SYNOPSIS
  40. *    handler = CmdStartup(name,dev_node,
  41. *        proc_port)
  42. *
  43. *    struct Handler *CmdStartup(STRPTR,struct DeviceNode *,
  44. *        struct MsgPort *);
  45. *
  46. *   FUNCTION
  47. *
  48. *   INPUTS
  49. *
  50. *   RESULT
  51. *
  52. *   EXAMPLE
  53. *
  54. *   NOTES
  55. *
  56. *   BUGS
  57. *
  58. *   SEE ALSO
  59. *
  60. ****************************************************************************
  61. *
  62. */
  63.  
  64. struct Handler *CmdStartup(STRPTR name,struct DeviceNode *dev_node,
  65.    struct MsgPort *proc_port)
  66. {
  67.    struct DosList *volume,*dos_list;
  68.    struct Handler *handler;
  69.    struct Object *root_dir;
  70.    struct MsgPort *port;
  71.    LONG error;
  72.    APTR base;
  73.  
  74.    /* Open extra libraries */
  75.  
  76.    error=0;
  77.    base=OpenLibrary(utility_name,UTILITY_VERSION);
  78.    if(base!=NULL)
  79.       UtilityBase=base;
  80.    else
  81.       error=1;
  82.  
  83.    base=OpenLibrary(locale_name,LOCALE_VERSION);
  84.    if(base!=NULL)
  85.       LocaleBase=base;
  86.    else
  87.       error=1;
  88.  
  89.    /* Initialise private handler structure */
  90.  
  91.    handler=AllocMem(sizeof(struct Handler),MEMF_CLEAR);
  92.  
  93.    if(handler==NULL)
  94.       error=IoErr();
  95.  
  96.    if(error==0)
  97.    {
  98.       handler->proc_port=proc_port;
  99.       handler->block_count=MEMBLOCKS(StrSize(default_vol_name))+
  100.          MEMBLOCKS(sizeof(struct Handler));
  101.       handler->min_block_size=MIN_BLOCK_SIZE;
  102.       handler->max_block_size=MAX_BLOCK_SIZE;
  103.  
  104.       dev_node->dn_Task=proc_port;
  105.    }
  106.  
  107.    /* Create a volume dos node */
  108.  
  109.    volume=MyMakeDosEntry(default_vol_name,DLT_VOLUME);
  110.    if(volume==NULL)
  111.       error=IoErr();
  112.  
  113.    if(error==0)
  114.    {
  115.       volume->dol_Task=proc_port;
  116.       DateStamp(&volume->dol_misc.dol_volume.dol_VolumeDate);
  117.       volume->dol_misc.dol_volume.dol_DiskType=ID_DOS_DISK;
  118.  
  119.       /* Put volume node into dos list */
  120.  
  121.       dos_list=LockDosList(LDF_WRITE|LDF_ALL);
  122.       AddDosEntry(volume);
  123.       handler->volume=volume;
  124.       UnLockDosList(LDF_WRITE|LDF_ALL);
  125.    }
  126.  
  127.    /* Open default locale */
  128.  
  129.    handler->locale=OpenLocale(NULL);
  130.  
  131.    /* Initialise notification handling */
  132.  
  133.    NewList((APTR)&handler->notifications);
  134.    port=CreateMsgPort();
  135.    handler->notify_port=port;
  136.    if(port==NULL)
  137.       error=ERROR_NO_FREE_STORE;
  138.  
  139.    /* Create the root directory and get a shared lock on it */
  140.  
  141.    root_dir=CreateObject(handler,default_vol_name,ST_ROOT,NULL);
  142.    handler->root_dir=root_dir;
  143.    if(root_dir!=NULL)
  144.    {
  145.       if(LockObject(handler,root_dir,ACCESS_READ)==NULL)
  146.          error=IoErr();
  147.    }
  148.    else
  149.       error=IoErr();
  150.  
  151.    /* Shut down handler if an error occurred */
  152.  
  153.    if(error!=0)
  154.       CmdDie(handler);
  155.  
  156.    /* Return result */
  157.  
  158.    SetIoErr(error);
  159.    return handler;
  160. }
  161.  
  162.  
  163.  
  164. /****i* ram.handler/CmdDie *************************************************
  165. *
  166. *   NAME
  167. *    CmdDie --
  168. *
  169. *   SYNOPSIS
  170. *    success = CmdDie(handler)
  171. *
  172. *    BOOL CmdDie(struct Handler *);
  173. *
  174. *   FUNCTION
  175. *
  176. *   INPUTS
  177. *
  178. *   RESULT
  179. *
  180. *   EXAMPLE
  181. *
  182. *   NOTES
  183. *
  184. *   BUGS
  185. *
  186. *   SEE ALSO
  187. *
  188. ****************************************************************************
  189. *
  190. */
  191.  
  192. BOOL CmdDie(struct Handler *handler)
  193. {
  194.    struct DosList *volume;
  195.    struct Object *root_dir;
  196.    struct Lock *root_lock;
  197.    LONG error;
  198.    APTR base;
  199.  
  200.    error=0;
  201.    if(handler!=NULL)
  202.    {
  203.       if(handler->lock_count>1)
  204.          error=ERROR_OBJECT_IN_USE;
  205.  
  206.       if(error==0)
  207.       {
  208.          root_dir=handler->root_dir;
  209.          if(root_dir!=NULL)
  210.          {
  211.             root_lock=root_dir->lock;
  212.             if(root_lock!=NULL)
  213.                CmdFreeLock(handler,root_lock);
  214.             DeleteObject(handler,root_dir);
  215.          }
  216.  
  217.          volume=handler->volume;
  218.          if(volume!=NULL)
  219.          {
  220.             RemDosEntry(volume);
  221.             MyFreeDosEntry(volume);
  222.          }
  223.          CloseLocale(handler->locale);
  224.          DeleteMsgPort(handler->notify_port);
  225.          FreeMem(handler,sizeof(struct Handler));
  226.       }
  227.  
  228.    }
  229.  
  230.    /* Close libraries */
  231.  
  232.    base=LocaleBase;
  233.    if(base!=NULL)
  234.       CloseLibrary(base);
  235.  
  236.    base=UtilityBase;
  237.    if(base!=NULL)
  238.       CloseLibrary(base);
  239.  
  240.    /* Return success indicator */
  241.  
  242.    SetIoErr(error);
  243.    return error==0;
  244. }
  245.  
  246.  
  247.  
  248. /****i* ram.handler/CmdIsFileSystem ****************************************
  249. *
  250. *   NAME
  251. *    CmdIsFileSystem --
  252. *
  253. *   SYNOPSIS
  254. *    result = CmdIsFileSystem()
  255. *
  256. *    BOOL CmdIsFileSystem();
  257. *
  258. *   FUNCTION
  259. *
  260. *   INPUTS
  261. *
  262. *   RESULT
  263. *
  264. *   EXAMPLE
  265. *
  266. *   NOTES
  267. *
  268. *   BUGS
  269. *
  270. *   SEE ALSO
  271. *
  272. ****************************************************************************
  273. *
  274. */
  275.  
  276. BOOL CmdIsFileSystem()
  277. {
  278.    return TRUE;
  279. }
  280.  
  281.  
  282.  
  283. /****i* ram.handler/CmdFind ************************************************
  284. *
  285. *   NAME
  286. *    CmdFind --
  287. *
  288. *   SYNOPSIS
  289. *    success = CmdFind(handler,handle,lock,
  290. *        name,mode)
  291. *
  292. *    BOOL CmdFind(struct Handler *,struct FileHandle *,struct Lock *,
  293. *        TEXT *,ULONG);
  294. *
  295. *   FUNCTION
  296. *
  297. *   INPUTS
  298. *
  299. *   RESULT
  300. *
  301. *   EXAMPLE
  302. *
  303. *   NOTES
  304. *
  305. *   BUGS
  306. *
  307. *   SEE ALSO
  308. *
  309. ****************************************************************************
  310. *
  311. */
  312.  
  313. #if 0
  314. BOOL CmdFind(struct Handler *handler,struct FileHandle *handle,
  315.    struct Lock *lock,const TEXT *name,ULONG mode)
  316. {
  317.    LONG error=0;
  318.    ULONG access;
  319.    struct Object *file,*old_file,*new_file=NULL,*parent;
  320.  
  321.    /* Set access mode */
  322.  
  323.    if(mode==MODE_OLDFILE)
  324.       access=ACCESS_READ;
  325.    else
  326.       access=ACCESS_WRITE;
  327.  
  328.    /* Get file */
  329.  
  330.    if((mode==MODE_NEWFILE)&&(handler->locked))
  331.       error=ERROR_DISK_WRITE_PROTECTED;
  332.  
  333.    old_file=GetObject(handler,lock,name,&parent);
  334.    lock=NULL;
  335.  
  336.    if(parent==NULL)
  337.       error=IoErr();
  338.  
  339.    if((error==0)&&(access==ACCESS_WRITE)&&(old_file==NULL))
  340.    {
  341.  
  342.       file=new_file=CreateObject(handler,name,ST_FILE,parent);
  343.       if(new_file==NULL)
  344.          error=IoErr();
  345.    }
  346.  
  347.    /* Get a lock on the file */
  348.  
  349.    if(error==0)
  350.    {
  351.       lock=LockObject(handler,file,access);
  352.       if(lock==NULL)
  353.          error=IoErr();
  354.    }
  355.  
  356.    /* Open file */
  357.  
  358.    if(error==0)
  359.    {
  360.       if(mode==MODE_NEWFILE)
  361.          lock->changed=TRUE;
  362.       if(!CmdFHFromLock(handle,lock))
  363.          error=IoErr();
  364.    }
  365.  
  366.    if((error==0)&&(mode==MODE_NEWFILE))
  367.    {
  368.       if(DeleteObject(handler,old_file))
  369.          error=IoErr();
  370.       file=NULL;
  371.    }
  372.  
  373.    if(error!=0)
  374.    {
  375.       if(lock!=NULL)
  376.          CmdFreeLock(handler,lock);
  377.       if(new_file!=NULL)
  378.       DeleteObject(handler,new_file))
  379.       Remove((struct Node *)object);
  380.       AddTail((struct List *)&parent->elements,(struct Node *)object);
  381.  
  382.    }
  383.  
  384.    /* Set error and return success code */
  385.  
  386.    SetIoErr(error);
  387.    return error==0;
  388. }
  389. #endif
  390.  
  391.  
  392. BOOL CmdFind(struct Handler *handler,struct FileHandle *handle,
  393.    struct Lock *lock,const TEXT *name,ULONG type)
  394. {
  395.    LONG error=0;
  396.    ULONG mode;
  397.    struct Object *file,*parent;
  398.  
  399.    /* Set access mode */
  400.  
  401.    if(type==MODE_OLDFILE)
  402.       mode=ACCESS_READ;
  403.    else
  404.       mode=ACCESS_WRITE;
  405.  
  406.    /* Get file */
  407.  
  408.    if((type==MODE_NEWFILE)&&(handler->locked))
  409.       error=ERROR_DISK_WRITE_PROTECTED;
  410.  
  411.    if(error==0)
  412.    {
  413.       file=GetObject(handler,lock,name,&parent);
  414.  
  415. /*#ifdef AMIGAOS*/
  416.       if(type==MODE_READWRITE)
  417.       {
  418.          if((file==NULL)&&(parent!=NULL))
  419.             file=CreateObject(handler,name,ST_FILE,parent);
  420.       }
  421. /*#endif*/
  422.  
  423.       if(type==MODE_NEWFILE)
  424.       {
  425.          if(parent!=NULL)
  426.          {
  427.             if(DeleteObject(handler,file))
  428.                file=CreateObject(handler,name,ST_FILE,parent);
  429.             else
  430.                file=NULL;
  431.          }
  432.       }
  433.  
  434.       if(file==NULL)
  435.          error=IoErr();
  436.    }
  437.  
  438.    /* Get a lock on the file */
  439.  
  440.    if(error==0)
  441.    {
  442.       lock=LockObject(handler,file,mode);
  443.       if(lock==NULL)
  444.          error=IoErr();
  445.       else if(type==MODE_NEWFILE)
  446.          lock->changed=TRUE;
  447.    }
  448.  
  449.    /* Open file */
  450.  
  451.    if(error==0)
  452.    {
  453.       if(!CmdFHFromLock(handle,lock))
  454.       {
  455.          error=IoErr();
  456.          CmdFreeLock(handler,lock);
  457.       }
  458.    }
  459.  
  460.    /* Set error and return success code */
  461.  
  462.    SetIoErr(error);
  463.    return error==0;
  464. }
  465.  
  466.  
  467.  
  468. /****i* ram.handler/CmdFHFromLock ******************************************
  469. *
  470. *   NAME
  471. *    CmdFHFromLock --
  472. *
  473. *   SYNOPSIS
  474. *    success = CmdFHFromLock(handle,lock)
  475. *
  476. *    BOOL CmdFHFromLock(struct FileHandle *,struct Lock *);
  477. *
  478. *   FUNCTION
  479. *
  480. *   INPUTS
  481. *
  482. *   RESULT
  483. *
  484. *   EXAMPLE
  485. *
  486. *   NOTES
  487. *
  488. *   BUGS
  489. *
  490. *   SEE ALSO
  491. *
  492. ****************************************************************************
  493. *
  494. */
  495.  
  496. BOOL CmdFHFromLock(struct FileHandle *handle,struct Lock *lock)
  497. {
  498.    LONG error=0;
  499.    struct Opening *opening;
  500.    struct Object *file;
  501.  
  502.    /* Check if access is allowed */
  503.  
  504.    file=(APTR)((struct FileLock *)lock)->fl_Key;
  505.    if(((struct Node *)file)->ln_Pri!=ST_FILE)
  506.       error=ERROR_OBJECT_WRONG_TYPE;
  507.  
  508.    /* Create and initialise "opening" */
  509.  
  510.    if(error==0)
  511.    {
  512.       opening=AllocMem(sizeof(struct Opening),MEMF_CLEAR);
  513.       if(opening!=NULL)
  514.       {
  515.          opening->file=file;
  516.          opening->block=(struct Block *)file->elements.mlh_Head;
  517.       }
  518.       else
  519.          error=IoErr();
  520.    }
  521.  
  522.    /* Put address of opening in file handle */
  523.  
  524.    handle->fh_Arg1=(PINT)opening;
  525.  
  526.    /* Set error and return success code */
  527.  
  528.    SetIoErr(error);
  529.    return error==0;
  530. }
  531.  
  532.  
  533.  
  534. /****i* ram.handler/CmdEnd *************************************************
  535. *
  536. *   NAME
  537. *    CmdEnd --
  538. *
  539. *   SYNOPSIS
  540. *    success = CmdEnd(handler,opening)
  541. *
  542. *    BOOL CmdEnd(struct Handler *,struct Opening *);
  543. *
  544. *   FUNCTION
  545. *
  546. *   INPUTS
  547. *
  548. *   RESULT
  549. *
  550. *   EXAMPLE
  551. *
  552. *   NOTES
  553. *
  554. *   BUGS
  555. *
  556. *   SEE ALSO
  557. *
  558. ****************************************************************************
  559. *
  560. */
  561.  
  562. BOOL CmdEnd(struct Handler *handler,struct Opening *opening)
  563. {
  564.    struct Object *file,*parent;
  565.    struct Lock *lock;
  566.    LONG error;
  567.  
  568.    /* Close file and update its date and flags */
  569.  
  570.    error=0;
  571.    file=opening->file;
  572.    lock=file->lock;
  573.    if(lock->changed)
  574.    {
  575.       if(!handler->locked)
  576.       {
  577.          file->protection&=~FIBF_ARCHIVE;
  578.          DateStamp(&file->date);
  579.          parent=file->parent;
  580.          if(parent!=NULL)
  581.          {
  582.             parent->protection&=~FIBF_ARCHIVE;
  583.             CopyMem(&file->date,&parent->date,sizeof(struct DateStamp));
  584.          }
  585.  
  586.          NotifyAll(handler,file,TRUE);
  587.       }
  588.       else
  589.          error=ERROR_DISK_WRITE_PROTECTED;
  590.    }
  591.    if(error==0)
  592.    {
  593.       CmdFreeLock(handler,lock);
  594.       FreeMem(opening,sizeof(struct Opening));
  595.    }
  596.  
  597.    /* Return success indicator */
  598.  
  599.    SetIoErr(error);
  600.    return error==0;
  601. }
  602.  
  603.  
  604.  
  605. /****i* ram.handler/CmdRead ************************************************
  606. *
  607. *   NAME
  608. *    CmdRead --
  609. *
  610. *   SYNOPSIS
  611. *    actual_length = CmdRead(opening,buffer,length)
  612. *
  613. *    UPINT CmdRead(struct Opening *,UBYTE *,UPINT);
  614. *
  615. *   FUNCTION
  616. *
  617. *   INPUTS
  618. *
  619. *   RESULT
  620. *
  621. *   EXAMPLE
  622. *
  623. *   NOTES
  624. *
  625. *   BUGS
  626. *
  627. *   SEE ALSO
  628. *
  629. ****************************************************************************
  630. *
  631. */
  632.  
  633. UPINT CmdRead(struct Opening *opening,UBYTE *buffer,UPINT length)
  634. {
  635.    LONG error;
  636.    struct Object *file;
  637.    struct Lock *lock;
  638.  
  639.    /* Read file if it isn't read protected */
  640.  
  641.    error=0;
  642.    file=opening->file;
  643.    lock=file->lock;
  644.  
  645.    if(file->protection&FIBF_READ)
  646.       error=ERROR_READ_PROTECTED;
  647.  
  648.    if(error==0)
  649.    {
  650.       length=ReadData(opening,buffer,length);
  651.       error=IoErr();
  652.    }
  653.    else
  654.    {
  655.       length=-1;
  656.    }
  657.  
  658.    /* Return number of bytes read */
  659.  
  660.    SetIoErr(error);
  661.    return length;
  662. }
  663.  
  664.  
  665.  
  666. /****i* ram.handler/CmdWrite ***********************************************
  667. *
  668. *   NAME
  669. *    CmdWrite --
  670. *
  671. *   SYNOPSIS
  672. *    actual_length = CmdWrite(handler,opening,buffer,length)
  673. *
  674. *    UPINT CmdWrite(struct Handler *,struct Opening *,UBYTE *,UPINT);
  675. *
  676. *   FUNCTION
  677. *
  678. *   INPUTS
  679. *
  680. *   RESULT
  681. *
  682. *   EXAMPLE
  683. *
  684. *   NOTES
  685. *
  686. *   BUGS
  687. *
  688. *   SEE ALSO
  689. *
  690. ****************************************************************************
  691. *
  692. */
  693.  
  694. UPINT CmdWrite(struct Handler *handler,struct Opening *opening,
  695.    UBYTE *buffer,UPINT length)
  696. {
  697.    LONG error;
  698.    struct Object *file;
  699.    struct Lock *lock;
  700.  
  701.    /* Write to file if it isn't write protected */
  702.  
  703.    error=0;
  704.    file=opening->file;
  705.    lock=file->lock;
  706.  
  707. #ifndef AMIGAOS
  708.    if(((struct FileLock *)lock)->fl_Access==ACCESS_READ)
  709.       error=ERROR_OBJECT_IN_USE;
  710.                                  /* ERROR_WRONG_LOCK_TYPE would be better */
  711. #endif
  712.  
  713.    if(file->protection&FIBF_WRITE)
  714.       error=ERROR_WRITE_PROTECTED;
  715.  
  716.    if(handler->locked)
  717.       error=ERROR_DISK_WRITE_PROTECTED;
  718.  
  719.    if(error==0)
  720.    {
  721.       length=WriteData(handler,opening,buffer,length);
  722.       error=IoErr();
  723.       if(length>0)
  724.          lock->changed=TRUE;
  725.    }
  726.    else
  727.    {
  728.       length=-1;
  729.    }
  730.  
  731.    /* Return number of bytes written */
  732.  
  733.    SetIoErr(error);
  734.    return length;
  735. }
  736.  
  737.  
  738.  
  739. /****i* ram.handler/CmdSeek ************************************************
  740. *
  741. *   NAME
  742. *    CmdSeek --
  743. *
  744. *   SYNOPSIS
  745. *    old_pos = CmdSeek(opening,offset,mode)
  746. *
  747. *    PINT CmdSeek(struct Opening *,PINT,LONG);
  748. *
  749. *   FUNCTION
  750. *
  751. *   INPUTS
  752. *
  753. *   RESULT
  754. *
  755. *   EXAMPLE
  756. *
  757. *   NOTES
  758. *
  759. *   BUGS
  760. *
  761. *   SEE ALSO
  762. *
  763. ****************************************************************************
  764. *
  765. * Note: Being at EOF is represented by the current block being the dummy
  766. * tail and the block position being zero.
  767. *
  768. */
  769.  
  770. UPINT CmdSeek(struct Opening *opening,PINT offset,LONG mode)
  771. {
  772.    struct Block *block;
  773.    struct Object *file;
  774.    UPINT block_pos,block_length,remainder,old_pos,new_pos;
  775.  
  776.    /* Get starting point */
  777.  
  778.    file=opening->file;
  779.    old_pos=opening->pos;
  780.  
  781.    if(mode==OFFSET_BEGINNING)
  782.    {
  783.       block=(APTR)file->elements.mlh_Head;
  784.       new_pos=block_pos=0;
  785.    }
  786.    else if(mode==OFFSET_CURRENT)
  787.    {
  788.       block=opening->block;
  789.       block_pos=opening->block_pos;
  790.       new_pos=old_pos;
  791.    }
  792.    else
  793.    {
  794.       block=(APTR)&file->elements.mlh_Tail;
  795.       block_pos=0;
  796.       new_pos=file->length;
  797.    }
  798.  
  799.    /* Check new position is within file */
  800.  
  801.    new_pos+=offset;
  802.    if(new_pos>file->length)
  803.    {
  804.       SetIoErr(ERROR_SEEK_ERROR);
  805.       return -1;
  806.    }
  807.  
  808.    if(offset>=0)
  809.    {
  810.       /* Go forwards */
  811.  
  812.       block_length=GetBlockLength(file,block);
  813.       remainder=offset+block_pos;
  814.       while((remainder>=block_length)&&(remainder>0))
  815.       {
  816.          remainder-=block_length;
  817.          block=(APTR)((struct MinNode *)block)->mln_Succ;
  818.          block_length=GetBlockLength(file,block);
  819.       }
  820.  
  821.       block_pos=remainder;
  822.    }
  823.    else
  824.    {
  825.       /* Go backwards */
  826.  
  827.       block_length=block_pos;
  828.       remainder=-offset;
  829.       while(remainder>block_length)
  830.       {
  831.          remainder-=block_length;
  832.          block=(APTR)((struct MinNode *)block)->mln_Pred;
  833.          block_length=GetBlockLength(file,block);
  834.       }
  835.  
  836.       block_pos=block_length-remainder;
  837.    }
  838.  
  839.    /* Record new position for next access */
  840.  
  841.    opening->block=block;
  842.    opening->block_pos=block_pos;
  843.    opening->pos=new_pos;
  844.  
  845.    /* Return old position */
  846.  
  847.    return old_pos;
  848. }
  849.  
  850.  
  851.  
  852. /****i* ram.handler/CmdSetFileSize *****************************************
  853. *
  854. *   NAME
  855. *    CmdSetFileSize --
  856. *
  857. *   SYNOPSIS
  858. *    new_length = CmdSetFileSize(handler,opening,offset,mode)
  859. *
  860. *    PINT CmdSetFileSize(struct Handler *,struct Opening *,PINT,LONG);
  861. *
  862. *   FUNCTION
  863. *
  864. *   INPUTS
  865. *
  866. *   RESULT
  867. *
  868. *   EXAMPLE
  869. *
  870. *   NOTES
  871. *
  872. *   BUGS
  873. *
  874. *   SEE ALSO
  875. *
  876. ****************************************************************************
  877. *
  878. */
  879.  
  880. PINT CmdSetFileSize(struct Handler *handler,struct Opening *opening,
  881.    PINT offset,LONG mode)
  882. {
  883.    LONG error,new_size;
  884.    struct Object *file;
  885.    struct Lock *lock;
  886.  
  887.    /* Change file size if it's open for writing */
  888.  
  889.    error=0;
  890.    file=opening->file;
  891.    lock=file->lock;
  892.  
  893.    if(((struct FileLock *)lock)->fl_Access==ACCESS_READ)
  894.       error=ERROR_OBJECT_IN_USE;
  895.    if(file->protection&FIBF_WRITE)
  896.       error=ERROR_WRITE_PROTECTED;
  897.    if(handler->locked)
  898.       error=ERROR_DISK_WRITE_PROTECTED;
  899.  
  900.    if(error==0)
  901.    {
  902.       new_size=ChangeFileSize(handler,opening,offset,mode);
  903.       if(new_size==-1)
  904.          error=IoErr();
  905.       else
  906.          lock->changed=TRUE;
  907.    }
  908.    else
  909.       new_size=-1;
  910.  
  911.    /* Return new file size */
  912.  
  913.    SetIoErr(error);
  914.    return new_size;
  915. }
  916.  
  917.  
  918.  
  919. /****i* ram.handler/CmdLocateObject ****************************************
  920. *
  921. *   NAME
  922. *    CmdLocateObject --
  923. *
  924. *   SYNOPSIS
  925. *    lock = CmdLocateObject(handler,lock,name,
  926. *        mode)
  927. *
  928. *    struct Lock *CmdLocateObject(struct Handler *,struct Lock *,TEXT *,
  929. *        ULONG);
  930. *
  931. *   FUNCTION
  932. *
  933. *   INPUTS
  934. *
  935. *   RESULT
  936. *
  937. *   EXAMPLE
  938. *
  939. *   NOTES
  940. *
  941. *   BUGS
  942. *
  943. *   SEE ALSO
  944. *
  945. ****************************************************************************
  946. *
  947. */
  948.  
  949. struct Lock *CmdLocateObject(struct Handler *handler,
  950.    struct Lock *lock,const TEXT *name,ULONG mode)
  951. {
  952.    LONG error=0;
  953.    struct Object *object;
  954.  
  955.    /* Find the object and lock it */
  956.  
  957.    object=GetObject(handler,lock,name,NULL);
  958.  
  959.    if(object!=NULL)
  960.       lock=LockObject(handler,object,mode);
  961.    else
  962.       lock=NULL;
  963.  
  964.    if(lock==NULL)
  965.       error=IoErr();
  966.  
  967.    /* Return result */
  968.  
  969.    SetIoErr(error);
  970.    return lock;
  971. }
  972.  
  973.  
  974.  
  975. /****i* ram.handler/CmdFreeLock ********************************************
  976. *
  977. *   NAME
  978. *    CmdFreeLock --
  979. *
  980. *   SYNOPSIS
  981. *    success = CmdFreeLock(handler,lock)
  982. *
  983. *    BOOL CmdFreeLock(struct Handler *,struct Lock *);
  984. *
  985. *   FUNCTION
  986. *
  987. *   INPUTS
  988. *    lock - May be NULL.
  989. *
  990. *   RESULT
  991. *
  992. *   EXAMPLE
  993. *
  994. *   NOTES
  995. *
  996. *   BUGS
  997. *
  998. *   SEE ALSO
  999. *
  1000. ****************************************************************************
  1001. *
  1002. */
  1003.  
  1004. BOOL CmdFreeLock(struct Handler *handler,struct Lock *lock)
  1005. {
  1006.    struct Object *object;
  1007.  
  1008.    if(lock!=NULL)
  1009.    {
  1010.       object=(APTR)((struct FileLock *)lock)->fl_Key;
  1011.  
  1012.       handler->lock_count--;
  1013.       if((--lock->lock_count)==0)
  1014.       {
  1015.          FreeMem(lock,sizeof(struct Lock));
  1016.          object->lock=NULL;
  1017.       }
  1018.    }
  1019.  
  1020.    return TRUE;
  1021. }
  1022.  
  1023.  
  1024.  
  1025. /****i* ram.handler/CmdCopyDir *********************************************
  1026. *
  1027. *   NAME
  1028. *    CmdCopyDir --
  1029. *
  1030. *   SYNOPSIS
  1031. *    lock = CmdCopyDir(handler,lock)
  1032. *
  1033. *    struct Lock *CmdCopyDir(struct Handler *,struct Lock *);
  1034. *
  1035. *   FUNCTION
  1036. *
  1037. *   INPUTS
  1038. *
  1039. *   RESULT
  1040. *
  1041. *   EXAMPLE
  1042. *
  1043. *   NOTES
  1044. *
  1045. *   BUGS
  1046. *
  1047. *   SEE ALSO
  1048. *
  1049. ****************************************************************************
  1050. *
  1051. */
  1052.  
  1053. struct Lock *CmdCopyDir(struct Handler *handler,struct Lock *lock)
  1054. {
  1055.    lock=FixLock(handler,lock);
  1056.    lock=LockObject(handler,(APTR)((struct FileLock *)lock)->fl_Key,
  1057.       ACCESS_READ);
  1058.  
  1059.    return lock;
  1060. }
  1061.  
  1062.  
  1063.  
  1064. /****i* ram.handler/CmdCopyDirFH *******************************************
  1065. *
  1066. *   NAME
  1067. *    CmdCopyDirFH --
  1068. *
  1069. *   SYNOPSIS
  1070. *    lock = CmdCopyDirFH(handler,opening)
  1071. *
  1072. *    struct Lock *CmdCopyDirFH(struct Handler *,struct Opening *);
  1073. *
  1074. *   FUNCTION
  1075. *
  1076. *   INPUTS
  1077. *
  1078. *   RESULT
  1079. *
  1080. *   EXAMPLE
  1081. *
  1082. *   NOTES
  1083. *
  1084. *   BUGS
  1085. *
  1086. *   SEE ALSO
  1087. *
  1088. ****************************************************************************
  1089. *
  1090. */
  1091.  
  1092. struct Lock *CmdCopyDirFH(struct Handler *handler,
  1093.    struct Opening *opening)
  1094. {
  1095.    return LockObject(handler,opening->file,ACCESS_READ);
  1096. }
  1097.  
  1098.  
  1099.  
  1100. /****i* ram.handler/CmdParent **********************************************
  1101. *
  1102. *   NAME
  1103. *    CmdParent --
  1104. *
  1105. *   SYNOPSIS
  1106. *    lock = CmdParent(handler,lock)
  1107. *
  1108. *    struct Lock *CmdParent(struct Handler *,struct Lock *);
  1109. *
  1110. *   FUNCTION
  1111. *
  1112. *   INPUTS
  1113. *
  1114. *   RESULT
  1115. *
  1116. *   EXAMPLE
  1117. *
  1118. *   NOTES
  1119. *
  1120. *   BUGS
  1121. *
  1122. *   SEE ALSO
  1123. *
  1124. ****************************************************************************
  1125. *
  1126. */
  1127.  
  1128. struct Lock *CmdParent(struct Handler *handler,struct Lock *lock)
  1129. {
  1130.    struct Object *parent;
  1131.    LONG error;
  1132.  
  1133.    error=0;
  1134.    lock=FixLock(handler,lock);
  1135.  
  1136.    parent=((struct Object *)((struct FileLock *)lock)->fl_Key)->parent;
  1137.    if(parent!=NULL)
  1138.    {
  1139.       lock=LockObject(handler,parent,ACCESS_READ);
  1140.       if(lock==NULL)
  1141.          error=IoErr();
  1142.    }
  1143.    else
  1144.       lock=NULL;
  1145.  
  1146.    SetIoErr(error);
  1147.    return lock;
  1148. }
  1149.  
  1150.  
  1151.  
  1152. /****i* ram.handler/CmdParentFH ********************************************
  1153. *
  1154. *   NAME
  1155. *    CmdParentFH --
  1156. *
  1157. *   SYNOPSIS
  1158. *    lock = CmdParentFH(handler,opening)
  1159. *
  1160. *    struct Lock *CmdParentFH(struct Handler *,struct Opening *);
  1161. *
  1162. *   FUNCTION
  1163. *
  1164. *   INPUTS
  1165. *
  1166. *   RESULT
  1167. *
  1168. *   EXAMPLE
  1169. *
  1170. *   NOTES
  1171. *
  1172. *   BUGS
  1173. *
  1174. *   SEE ALSO
  1175. *
  1176. ****************************************************************************
  1177. *
  1178. */
  1179.  
  1180. struct Lock *CmdParentFH(struct Handler *handler,
  1181.    struct Opening *opening)
  1182. {
  1183.    struct Object *parent;
  1184.    struct Lock *lock;
  1185.  
  1186.    parent=opening->file->parent;
  1187.    lock=LockObject(handler,parent,ACCESS_READ);
  1188.  
  1189.    return lock;
  1190. }
  1191.  
  1192.  
  1193.  
  1194. /****i* ram.handler/CmdSameLock ********************************************
  1195. *
  1196. *   NAME
  1197. *    CmdSameLock --
  1198. *
  1199. *   SYNOPSIS
  1200. *    result = CmdSameLock(lock1,lock2)
  1201. *
  1202. *    BOOL CmdSameLock(struct Lock *,struct Lock *);
  1203. *
  1204. *   FUNCTION
  1205. *
  1206. *   INPUTS
  1207. *
  1208. *   RESULT
  1209. *
  1210. *   EXAMPLE
  1211. *
  1212. *   NOTES
  1213. *
  1214. *   BUGS
  1215. *
  1216. *   SEE ALSO
  1217. *
  1218. ****************************************************************************
  1219. *
  1220. */
  1221.  
  1222. BOOL CmdSameLock(struct Lock *lock1,struct Lock *lock2)
  1223. {
  1224.    SetIoErr(0);
  1225.    return lock1==lock2;
  1226. }
  1227.  
  1228.  
  1229.  
  1230. /****i* ram.handler/CmdCreateDir *******************************************
  1231. *
  1232. *   NAME
  1233. *    CmdCreateDir --
  1234. *
  1235. *   SYNOPSIS
  1236. *    lock = CmdCreateDir(handler,lock,name)
  1237. *
  1238. *    struct Lock *CmdCreateDir(struct Handler *,struct Lock *,TEXT *);
  1239. *
  1240. *   FUNCTION
  1241. *
  1242. *   INPUTS
  1243. *
  1244. *   RESULT
  1245. *
  1246. *   EXAMPLE
  1247. *
  1248. *   NOTES
  1249. *
  1250. *   BUGS
  1251. *
  1252. *   SEE ALSO
  1253. *
  1254. ****************************************************************************
  1255. *
  1256. */
  1257.  
  1258. struct Lock *CmdCreateDir(struct Handler *handler,
  1259.    struct Lock *lock,const TEXT *name)
  1260. {
  1261.    struct Object *dir,*parent;
  1262.    LONG error;
  1263.  
  1264.    /* Find parent directory and possible name clash */
  1265.  
  1266.    dir=GetObject(handler,lock,name,&parent);
  1267.    lock=NULL;
  1268.    error=0;
  1269.  
  1270.    /* Create a new directory */
  1271.  
  1272.    if(dir==NULL)
  1273.    {
  1274.       if(parent!=NULL)
  1275.       {
  1276.          if(!handler->locked)
  1277.          {
  1278.             dir=CreateObject(handler,name,ST_USERDIR,parent);
  1279.             if(dir!=NULL)
  1280.             {
  1281.                lock=LockObject(handler,dir,ACCESS_WRITE);
  1282.                if(lock!=NULL)
  1283.                   NotifyAll(handler,dir,FALSE);
  1284.                else
  1285.                {
  1286.                   error=IoErr();
  1287.                   DeleteObject(handler,dir);
  1288.                }
  1289.             }
  1290.             else
  1291.                error=IoErr();
  1292.          }
  1293.          else
  1294.             error=ERROR_DISK_WRITE_PROTECTED;
  1295.       }
  1296.       else
  1297.          error=ERROR_OBJECT_NOT_FOUND;
  1298.    }
  1299.    else
  1300.       error=ERROR_OBJECT_EXISTS;
  1301.  
  1302.    /* Set error code and return lock on new directory */
  1303.  
  1304.    SetIoErr(error);
  1305.    return lock;
  1306. }
  1307.  
  1308.  
  1309.  
  1310. /****i* ram.handler/CmdExamineObject ***************************************
  1311. *
  1312. *   NAME
  1313. *    CmdExamineObject --
  1314. *
  1315. *   SYNOPSIS
  1316. *    success = CmdExamineObject(handler,lock,
  1317. *        info)
  1318. *
  1319. *    BOOL CmdExamineObject(struct Handler *,struct Lock *,
  1320. *        struct FileInfoBlock *);
  1321. *
  1322. *   FUNCTION
  1323. *
  1324. *   INPUTS
  1325. *
  1326. *   RESULT
  1327. *
  1328. *   EXAMPLE
  1329. *
  1330. *   NOTES
  1331. *
  1332. *   BUGS
  1333. *
  1334. *   SEE ALSO
  1335. *
  1336. ****************************************************************************
  1337. *
  1338. */
  1339.  
  1340. BOOL CmdExamineObject(struct Handler *handler,struct Lock *lock,
  1341.    struct FileInfoBlock *info)
  1342. {
  1343.    lock=FixLock(handler,lock);
  1344.    return ExamineObject(handler,(APTR)((struct FileLock *)lock)->fl_Key,
  1345.       info);
  1346. }
  1347.  
  1348.  
  1349.  
  1350. /****i* ram.handler/CmdExamineFH *******************************************
  1351. *
  1352. *   NAME
  1353. *    CmdExamineFH --
  1354. *
  1355. *   SYNOPSIS
  1356. *    success = CmdExamineFH(handler,opening,
  1357. *        info)
  1358. *
  1359. *    BOOL CmdExamineFH(struct Handler *,struct Opening *,
  1360. *        struct FileInfoBlock *);
  1361. *
  1362. *   FUNCTION
  1363. *
  1364. *   INPUTS
  1365. *
  1366. *   RESULT
  1367. *
  1368. *   EXAMPLE
  1369. *
  1370. *   NOTES
  1371. *
  1372. *   BUGS
  1373. *
  1374. *   SEE ALSO
  1375. *
  1376. ****************************************************************************
  1377. *
  1378. */
  1379.  
  1380. BOOL CmdExamineFH(struct Handler *handler,struct Opening *opening,
  1381.    struct FileInfoBlock *info)
  1382. {
  1383.    return ExamineObject(handler,opening->file,info);
  1384. }
  1385.  
  1386.  
  1387.  
  1388. /****i* ram.handler/CmdExamineNext *****************************************
  1389. *
  1390. *   NAME
  1391. *    CmdExamineNext --
  1392. *
  1393. *   SYNOPSIS
  1394. *    success = CmdExamineNext(handler,info)
  1395. *
  1396. *    BOOL CmdExamineNext(struct Handler *,struct FileInfoBlock *);
  1397. *
  1398. *   FUNCTION
  1399. *
  1400. *   INPUTS
  1401. *
  1402. *   RESULT
  1403. *
  1404. *   EXAMPLE
  1405. *
  1406. *   NOTES
  1407. *
  1408. *   BUGS
  1409. *
  1410. *   SEE ALSO
  1411. *
  1412. ****************************************************************************
  1413. *
  1414. */
  1415.  
  1416. BOOL CmdExamineNext(struct Handler *handler,struct FileInfoBlock *info)
  1417. {
  1418.    return ExamineObject(handler,NULL,info);
  1419. }
  1420.  
  1421.  
  1422.  
  1423. /****i* ram.handler/CmdInfo ************************************************
  1424. *
  1425. *   NAME
  1426. *    CmdInfo --
  1427. *
  1428. *   SYNOPSIS
  1429. *    success = CmdInfo(handler,info_data)
  1430. *
  1431. *    BOOL CmdExamineObject(struct Handler *,struct InfoData *);
  1432. *
  1433. *   FUNCTION
  1434. *
  1435. *   INPUTS
  1436. *
  1437. *   RESULT
  1438. *
  1439. *   EXAMPLE
  1440. *
  1441. *   NOTES
  1442. *
  1443. *   BUGS
  1444. *
  1445. *   SEE ALSO
  1446. *
  1447. ****************************************************************************
  1448. *
  1449. */
  1450.  
  1451. BOOL CmdInfo(struct Handler *handler,struct InfoData *info_data)
  1452. {
  1453.    LONG disk_state;
  1454.  
  1455.    info_data->id_NumSoftErrors=0;
  1456.    info_data->id_UnitNumber=0;
  1457.    if(handler->locked)
  1458.       disk_state=ID_WRITE_PROTECTED;
  1459.    else
  1460.       disk_state=ID_VALIDATED;
  1461.    info_data->id_DiskState=disk_state;
  1462.    info_data->id_NumBlocks=handler->block_count
  1463.       +MEMBLOCKS(AvailMem(MEMF_ANY));
  1464.    info_data->id_NumBlocksUsed=handler->block_count;
  1465.    info_data->id_BytesPerBlock=MEM_BLOCKSIZE;
  1466.    info_data->id_DiskType=ID_DOS_DISK;
  1467.    info_data->id_VolumeNode=MKBADDR(handler->volume);
  1468.    if(handler->lock_count>1)
  1469.       info_data->id_InUse=DOSTRUE;
  1470.    else
  1471.       info_data->id_InUse=DOSFALSE;
  1472.  
  1473.    return TRUE;
  1474. }
  1475.  
  1476.  
  1477.  
  1478. /****i* ram.handler/CmdSetProtect ******************************************
  1479. *
  1480. *   NAME
  1481. *    CmdSetProtect --
  1482. *
  1483. *   SYNOPSIS
  1484. *    success = CmdSetProtect(handler,lock,name,flags)
  1485. *
  1486. *    BOOL CmdSetProtect(struct Handler *,struct Lock *,TEXT *,ULONG);
  1487. *
  1488. *   FUNCTION
  1489. *
  1490. *   INPUTS
  1491. *
  1492. *   RESULT
  1493. *
  1494. *   EXAMPLE
  1495. *
  1496. *   NOTES
  1497. *
  1498. *   BUGS
  1499. *
  1500. *   SEE ALSO
  1501. *
  1502. ****************************************************************************
  1503. *
  1504. */
  1505.  
  1506. BOOL CmdSetProtect(struct Handler *handler,struct Lock *lock,
  1507.    const TEXT *name,ULONG flags)
  1508. {
  1509.    LONG error;
  1510.    struct Object *object;
  1511.  
  1512.    /* Set new protection flags if object isn't in use */
  1513.  
  1514.    error=0;
  1515.    object=GetObject(handler,lock,name,NULL);
  1516.    if(object!=NULL)
  1517.    {
  1518.       if(handler->locked)
  1519.          error=ERROR_DISK_WRITE_PROTECTED;
  1520.  
  1521.       if(error==0)
  1522.       {
  1523.          object=GetRealObject(object);
  1524.          if(object->lock==NULL)
  1525.          {
  1526.             object->protection=flags;
  1527.             NotifyAll(handler,object,TRUE);
  1528.          }
  1529.          else
  1530.             error=ERROR_OBJECT_IN_USE;
  1531.       }
  1532.    }
  1533.    else
  1534.       error=IoErr();
  1535.  
  1536.    /* Return result */
  1537.  
  1538.    SetIoErr(error);
  1539.    return error==0;
  1540. }
  1541.  
  1542.  
  1543.  
  1544. /****i* ram.handler/CmdSetComment ******************************************
  1545. *
  1546. *   NAME
  1547. *    CmdSetComment --
  1548. *
  1549. *   SYNOPSIS
  1550. *    success = CmdSetComment(handler,lock,name,comment)
  1551. *
  1552. *    BOOL CmdSetComment(struct Handler *,struct Lock *,TEXT *,TEXT *);
  1553. *
  1554. *   FUNCTION
  1555. *
  1556. *   INPUTS
  1557. *
  1558. *   RESULT
  1559. *
  1560. *   EXAMPLE
  1561. *
  1562. *   NOTES
  1563. *
  1564. *   BUGS
  1565. *
  1566. *   SEE ALSO
  1567. *
  1568. ****************************************************************************
  1569. *
  1570. */
  1571.  
  1572. BOOL CmdSetComment(struct Handler *handler,struct Lock *lock,
  1573.    const TEXT *name,const TEXT *comment)
  1574. {
  1575.    LONG error;
  1576.    struct Object *object;
  1577.    const TEXT *p;
  1578.    TEXT ch;
  1579.    struct Locale *locale;
  1580.    PINT block_diff;
  1581.  
  1582.    /* Get object */
  1583.  
  1584.    error=0;
  1585.    object=GetObject(handler,lock,name,NULL);
  1586.    if(object==NULL)
  1587.       error=IoErr();
  1588.  
  1589.    /* Check comment isn't too long */
  1590.  
  1591.    if(StrSize(comment)>sizeof(((struct FileInfoBlock *)NULL)->fib_Comment))
  1592.       error=ERROR_COMMENT_TOO_BIG;
  1593.  
  1594.    /* Check comment doesn't have any strange characters in it */
  1595.  
  1596.    locale=handler->locale;
  1597.    for(p=comment;(ch=*p)!='\0';p++)
  1598.       if(!IsPrint(locale,ch)||IsCntrl(locale,ch))
  1599.          error=ERROR_INVALID_COMPONENT_NAME;
  1600.  
  1601.    /* Check volume isn't write-protected */
  1602.  
  1603.    if(handler->locked)
  1604.       error=ERROR_DISK_WRITE_PROTECTED;
  1605.  
  1606.    /* Store new comment */
  1607.  
  1608.    if(error==0)
  1609.    {
  1610.       block_diff=SetString(&object->comment,comment);
  1611.       if(block_diff==-1)
  1612.          error=IoErr();
  1613.       else
  1614.       {
  1615.          object->block_count+=block_diff;
  1616.          handler->block_count+=block_diff;
  1617.       }
  1618.    }
  1619.  
  1620.    /* Notify interested parties */
  1621.  
  1622.    if(error==0)
  1623.    {
  1624.       NotifyAll(handler,object,FALSE);
  1625.    }
  1626.  
  1627.    /* Return result */
  1628.  
  1629.    SetIoErr(error);
  1630.    return error==0;
  1631. }
  1632.  
  1633.  
  1634.  
  1635. /****i* ram.handler/CmdRenameObject ****************************************
  1636. *
  1637. *   NAME
  1638. *    CmdRenameObject --
  1639. *
  1640. *   SYNOPSIS
  1641. *    success = CmdRenameObject(handler,old_lock,old_name
  1642. *        new_lock,new_name)
  1643. *
  1644. *    BOOL CmdRenameObject(struct Handler *,struct Lock *,STRPTR,
  1645. *        struct Lock *,STRPTR);
  1646. *
  1647. *   FUNCTION
  1648. *
  1649. *   INPUTS
  1650. *
  1651. *   RESULT
  1652. *
  1653. *   EXAMPLE
  1654. *
  1655. *   NOTES
  1656. *
  1657. *   BUGS
  1658. *
  1659. *   SEE ALSO
  1660. *
  1661. ****************************************************************************
  1662. *
  1663. */
  1664.  
  1665. BOOL CmdRenameObject(struct Handler *handler,struct Lock *old_lock,
  1666.    STRPTR old_name,struct Lock *new_lock,STRPTR new_name)
  1667. {
  1668.    struct Object *parent,*object,*duplicate,*p;
  1669.    LONG error;
  1670.  
  1671.    /* Get object to be moved */
  1672.  
  1673.    error=0;
  1674.    object=GetObject(handler,old_lock,old_name,NULL);
  1675.    if(object==NULL)
  1676.       error=IoErr();
  1677.  
  1678.    /* Get destination directory and check if a different object already has
  1679.       the target name */
  1680.  
  1681.    duplicate=GetObject(handler,new_lock,new_name,&parent);
  1682.    if((duplicate!=NULL)&&(duplicate!=object))
  1683.       error=ERROR_OBJECT_EXISTS;
  1684.    if(parent==NULL)
  1685.       error=IoErr();
  1686.  
  1687.    /* Check for a circular rename */
  1688.  
  1689.    for(p=parent;p!=NULL;p=p->parent)
  1690.    {
  1691.       if(p==object)
  1692.          error=ERROR_OBJECT_NOT_FOUND;
  1693.    }
  1694.  
  1695.    /* Check volume isn't write-protected */
  1696.  
  1697.    if(handler->locked)
  1698.       error=ERROR_DISK_WRITE_PROTECTED;
  1699.  
  1700.    /* Give the object its new name */
  1701.  
  1702.    if(error==0)
  1703.    {
  1704.       if(!SetName(handler,object,FilePart(new_name)))
  1705.          error=IoErr();
  1706.    }
  1707.  
  1708.    if(error==0)
  1709.    {
  1710.       /* Remove object from its old parent and place it in its new parent */
  1711.  
  1712.       Remove((struct Node *)object);
  1713.       AddTail((struct List *)&parent->elements,(struct Node *)object);
  1714.       object->parent=parent;
  1715.  
  1716.       /* Update notifications */
  1717.  
  1718.       if(object!=duplicate)
  1719.       {
  1720.          NotifyAll(handler,object,FALSE);
  1721.          MatchNotifyRequests(handler);
  1722.          NotifyAll(handler,object,FALSE);
  1723.       }
  1724.    }
  1725.  
  1726.    /* Return success indicator */
  1727.  
  1728.    SetIoErr(error);
  1729.    return error==0;
  1730. }
  1731.  
  1732.  
  1733.  
  1734. /****i* ram.handler/CmdRenameDisk ******************************************
  1735. *
  1736. *   NAME
  1737. *    CmdRenameDisk --
  1738. *
  1739. *   SYNOPSIS
  1740. *    success = CmdRenameDisk(handler,new_name)
  1741. *
  1742. *    BOOL CmdRenameDisk(struct Handler *,STRPTR);
  1743. *
  1744. *   FUNCTION
  1745. *
  1746. *   INPUTS
  1747. *
  1748. *   RESULT
  1749. *
  1750. *   EXAMPLE
  1751. *
  1752. *   NOTES
  1753. *
  1754. *   BUGS
  1755. *
  1756. *   SEE ALSO
  1757. *
  1758. ****************************************************************************
  1759. *
  1760. */
  1761.  
  1762. BOOL CmdRenameDisk(struct Handler *handler,STRPTR new_name)
  1763. {
  1764.    LONG error=0;
  1765.  
  1766.    /* Check volume isn't write-protected */
  1767.  
  1768.    if(handler->locked)
  1769.       error=ERROR_DISK_WRITE_PROTECTED;
  1770.  
  1771.    /* Rename volume's DOS entry and root directory */
  1772.  
  1773.    if(error==0)
  1774.       if(!SetName(handler,handler->root_dir,new_name))
  1775.          error=IoErr();
  1776.  
  1777.    if(error==0)
  1778.       if(!MyRenameDosEntry(handler->volume,new_name))
  1779.          error=IoErr();
  1780.  
  1781.    /* Return success indicator */
  1782.  
  1783.    SetIoErr(error);
  1784.    return error==0;
  1785. }
  1786.  
  1787.  
  1788.  
  1789. /****i* ram.handler/CmdSetDate *********************************************
  1790. *
  1791. *   NAME
  1792. *    CmdSetDate --
  1793. *
  1794. *   SYNOPSIS
  1795. *    success = CmdSetDate(handler,lock,name,
  1796. *        date)
  1797. *
  1798. *    BOOL CmdSetDate(struct Handler *,struct Lock *,STRPTR,
  1799. *        struct DateStamp *);
  1800. *
  1801. *   FUNCTION
  1802. *
  1803. *   INPUTS
  1804. *
  1805. *   RESULT
  1806. *
  1807. *   EXAMPLE
  1808. *
  1809. *   NOTES
  1810. *
  1811. *   BUGS
  1812. *
  1813. *   SEE ALSO
  1814. *
  1815. ****************************************************************************
  1816. *
  1817. */
  1818.  
  1819. BOOL CmdSetDate(struct Handler *handler,struct Lock *lock,STRPTR name,
  1820.    struct DateStamp *date)
  1821. {
  1822.    struct Object *object;
  1823.    LONG error;
  1824.  
  1825.    /* Check volume isn't write-protected */
  1826.  
  1827.    error=0;
  1828.    if(handler->locked)
  1829.       error=ERROR_DISK_WRITE_PROTECTED;
  1830.  
  1831.    /* Get object and set its new date */
  1832.  
  1833.    if(error==0)
  1834.    {
  1835.       object=GetObject(handler,lock,name,NULL);
  1836.       if(object!=NULL)
  1837.          CopyMem(date,&object->date,sizeof(struct DateStamp));
  1838.       else
  1839.          error=IoErr();
  1840.    }
  1841.  
  1842.    /* Notify interested parties */
  1843.  
  1844.    if(error==0)
  1845.    {
  1846.       NotifyAll(handler,object,TRUE);
  1847.    }
  1848.  
  1849.    /* Return result */
  1850.  
  1851.    SetIoErr(error);
  1852.    return error==0;
  1853. }
  1854.  
  1855.  
  1856.  
  1857. /****i* ram.handler/CmdDeleteObject ****************************************
  1858. *
  1859. *   NAME
  1860. *    CmdDeleteObject --
  1861. *
  1862. *   SYNOPSIS
  1863. *    success = CmdDeleteObject(handler,lock,name)
  1864. *
  1865. *    BOOL CmdDeleteObject(struct Handler *,struct Lock *,STRPTR);
  1866. *
  1867. *   FUNCTION
  1868. *
  1869. *   INPUTS
  1870. *
  1871. *   RESULT
  1872. *
  1873. *   EXAMPLE
  1874. *
  1875. *   NOTES
  1876. *
  1877. *   BUGS
  1878. *
  1879. *   SEE ALSO
  1880. *
  1881. ****************************************************************************
  1882. *
  1883. */
  1884.  
  1885. BOOL CmdDeleteObject(struct Handler *handler,struct Lock *lock,
  1886.    STRPTR name)
  1887. {
  1888.    LONG error;
  1889.    struct Object *object;
  1890.  
  1891.    /* Find object and check it can be deleted */
  1892.  
  1893.    error=0;
  1894.    object=GetObject(handler,lock,name,NULL);
  1895.    if(object==NULL)
  1896.       error=IoErr();
  1897.  
  1898.    if(handler->locked)
  1899.       error=ERROR_DISK_WRITE_PROTECTED;
  1900.  
  1901.    if(error==0)
  1902.    {
  1903.       if(GetRealObject(object)->protection&FIBF_DELETE)
  1904.          error=ERROR_DELETE_PROTECTED;
  1905.    }
  1906.  
  1907.    /* Attempt to delete object and notify anyone who's interested */
  1908.  
  1909.    if(error==0)
  1910.    {
  1911.       if(DeleteObject(handler,object))
  1912.       {
  1913.          NotifyAll(handler,object,FALSE);
  1914.          MatchNotifyRequests(handler);
  1915.       }
  1916.       else
  1917.          error=IoErr();
  1918.    }
  1919.  
  1920.    /* Return result */
  1921.  
  1922.    SetIoErr(error);
  1923.    return error==0;
  1924. }
  1925.  
  1926.  
  1927.  
  1928. /****i* ram.handler/CmdCurrentVolume ***************************************
  1929. *
  1930. *   NAME
  1931. *    CmdCurrentVolume --
  1932. *
  1933. *   SYNOPSIS
  1934. *    volume = CmdCurrentVolume(handler)
  1935. *
  1936. *    struct DosList *CmdCurrentVolume(struct Handler *);
  1937. *
  1938. *   FUNCTION
  1939. *
  1940. *   INPUTS
  1941. *
  1942. *   RESULT
  1943. *
  1944. *   EXAMPLE
  1945. *
  1946. *   NOTES
  1947. *
  1948. *   BUGS
  1949. *
  1950. *   SEE ALSO
  1951. *
  1952. ****************************************************************************
  1953. *
  1954. */
  1955.  
  1956. struct DosList *CmdCurrentVolume(struct Handler *handler)
  1957. {
  1958.    SetIoErr(0);
  1959.    return handler->volume;
  1960. }
  1961.  
  1962.  
  1963.  
  1964. /****i* ram.handler/CmdChangeMode ******************************************
  1965. *
  1966. *   NAME
  1967. *    CmdChangeMode --
  1968. *
  1969. *   SYNOPSIS
  1970. *    success = CmdChangeMode(type,thing,new_mode)
  1971. *
  1972. *    BOOL CmdChangeMode(ULONG,APTR,ULONG);
  1973. *
  1974. *   FUNCTION
  1975. *
  1976. *   INPUTS
  1977. *
  1978. *   RESULT
  1979. *
  1980. *   EXAMPLE
  1981. *
  1982. *   NOTES
  1983. *
  1984. *   BUGS
  1985. *
  1986. *   SEE ALSO
  1987. *
  1988. ****************************************************************************
  1989. *
  1990. */
  1991.  
  1992. BOOL CmdChangeMode(ULONG type,APTR thing,ULONG new_mode)
  1993. {
  1994.    struct Lock *lock;
  1995.    struct Opening *opening;
  1996.    ULONG old_mode;
  1997.    LONG error=0;
  1998.  
  1999.    /* Get the lock */
  2000.  
  2001.    if(type==CHANGE_FH)
  2002.    {
  2003.       opening=(APTR)((struct FileHandle *)thing)->fh_Arg1;
  2004.       lock=opening->file->lock;
  2005.    }
  2006.    else
  2007.       lock=thing;
  2008.  
  2009.    /* Change mode if possible */
  2010.  
  2011.    old_mode=((struct FileLock *)lock)->fl_Access;
  2012.  
  2013.    if((new_mode==ACCESS_WRITE)&&(lock->lock_count>1))
  2014.    {
  2015.       error=ERROR_OBJECT_IN_USE;
  2016.    }
  2017.    else
  2018.    {
  2019.       ((struct FileLock *)lock)->fl_Access=new_mode;
  2020.    }
  2021.  
  2022.    /* Set error code and return result */
  2023.  
  2024.    SetIoErr(error);
  2025.    return error==0;
  2026. }
  2027.  
  2028.  
  2029.  
  2030. /****i* ram.handler/CmdMakeLink ********************************************
  2031. *
  2032. *   NAME
  2033. *    CmdMakeLink --
  2034. *
  2035. *   SYNOPSIS
  2036. *    success = CmdMakeLink(handler,lock,name,reference,
  2037. *        link_type)
  2038. *
  2039. *    BOOL CmdMakeLink(struct Handler *,struct Lock *,STRPTR,APTR,
  2040. *        LONG);
  2041. *
  2042. *   FUNCTION
  2043. *
  2044. *   INPUTS
  2045. *
  2046. *   RESULT
  2047. *
  2048. *   EXAMPLE
  2049. *
  2050. *   NOTES
  2051. *
  2052. *   BUGS
  2053. *
  2054. *   SEE ALSO
  2055. *
  2056. ****************************************************************************
  2057. *
  2058. */
  2059.  
  2060. BOOL CmdMakeLink(struct Handler *handler,struct Lock *lock,STRPTR name,
  2061.    APTR reference,LONG link_type)
  2062. {
  2063.    struct Object *link,*parent,*target,*master_link;
  2064.    LONG error,object_type;
  2065.    PINT block_diff;
  2066.    struct MinNode *node;
  2067.  
  2068.    /* Find parent directory and possible name clash */
  2069.  
  2070.    error=0;
  2071.    link=GetObject(handler,lock,name,&parent);
  2072.    if(link!=NULL)
  2073.       error=ERROR_OBJECT_EXISTS;
  2074.  
  2075.    /* Determine link type */
  2076.  
  2077.    if(link_type==LINK_HARD)
  2078.    {
  2079.       target=(APTR)((struct FileLock *)reference)->fl_Key;
  2080.       if(((struct Node *)target)->ln_Pri==ST_FILE)
  2081.          object_type=ST_LINKFILE;
  2082.       else
  2083.          object_type=ST_LINKDIR;
  2084.    }
  2085.    else
  2086.    {
  2087.       object_type=ST_SOFTLINK;
  2088.       error=ERROR_NOT_IMPLEMENTED;
  2089.    }
  2090.  
  2091.    /* Check volume isn't write-protected */
  2092.  
  2093.    if(error==0)
  2094.    {
  2095.       if(handler->locked)
  2096.          error=ERROR_DISK_WRITE_PROTECTED;
  2097.    }
  2098.  
  2099.    /* Create a new link */
  2100.  
  2101.    if(error==0)
  2102.    {
  2103.       if(parent!=NULL)
  2104.       {
  2105.          link=CreateObject(handler,name,object_type,parent);
  2106.          if(link==NULL)
  2107.             error=IoErr();
  2108.       }
  2109.       else
  2110.          error=ERROR_OBJECT_NOT_FOUND;
  2111.    }
  2112.  
  2113.    /* Store link target */
  2114.  
  2115.    if(error==0)
  2116.    {
  2117.       if(link_type==LINK_HARD)
  2118.       {
  2119.          node=target->hard_link.mln_Succ;
  2120.          if(node==NULL)
  2121.          {
  2122.             master_link=link;
  2123.             AddTail((APTR)&master_link->elements,(APTR)&target->hard_link);
  2124.          }
  2125.          else
  2126.             master_link=HARDLINK(node);
  2127.          AddTail((APTR)&master_link->elements,(APTR)&link->hard_link);
  2128.       }
  2129.       else
  2130.       {
  2131.          block_diff=SetString((APTR)&link->lock,reference);
  2132.          if(block_diff==-1)
  2133.             error=IoErr();
  2134.          else
  2135.          {
  2136.             link->block_count+=block_diff;
  2137.             handler->block_count+=block_diff;
  2138.          }
  2139.       }
  2140.    }
  2141.  
  2142.    /* Update notifications */
  2143.  
  2144.    if(error==0)
  2145.    {
  2146.       MatchNotifyRequests(handler);
  2147.       NotifyAll(handler,link,FALSE);
  2148.    }
  2149.  
  2150.    /* Return success indicator */
  2151.  
  2152.    SetIoErr(error);
  2153.    return error==0;
  2154. }
  2155.  
  2156.  
  2157.  
  2158. /****i* ram.handler/CmdWriteProtect ****************************************
  2159. *
  2160. *   NAME
  2161. *    CmdWriteProtect --
  2162. *
  2163. *   SYNOPSIS
  2164. *    success = CmdWriteProtect(handler,on,key)
  2165. *
  2166. *    BOOL CmdWriteProtect(struct Handler *,BOOL,ULONG);
  2167. *
  2168. *   FUNCTION
  2169. *
  2170. *   INPUTS
  2171. *
  2172. *   RESULT
  2173. *
  2174. *   EXAMPLE
  2175. *
  2176. *   NOTES
  2177. *
  2178. *   BUGS
  2179. *
  2180. *   SEE ALSO
  2181. *
  2182. ****************************************************************************
  2183. *
  2184. */
  2185.  
  2186. BOOL CmdWriteProtect(struct Handler *handler,BOOL on,ULONG key)
  2187. {
  2188.    LONG error;
  2189.    struct Object *root_dir;
  2190.  
  2191.    error=0;
  2192.    root_dir=handler->root_dir;
  2193.  
  2194.    if(on)
  2195.    {
  2196.       if(!handler->locked)
  2197.          root_dir->length=key;
  2198.       else
  2199.          error=ERROR_DISK_WRITE_PROTECTED;
  2200.    }
  2201.    else
  2202.    {
  2203.       if((root_dir->length!=0)&&(root_dir->length!=key))
  2204.          error=ERROR_INVALID_COMPONENT_NAME;
  2205.       else
  2206.          root_dir->length=0;
  2207.    }
  2208.  
  2209.    if(error==0)
  2210.       handler->locked=on;
  2211.  
  2212.    /* Return success indicator */
  2213.  
  2214.    SetIoErr(error);
  2215.    return error==0;
  2216. }
  2217.  
  2218.  
  2219.  
  2220. /****i* ram.handler/CmdFlush ***********************************************
  2221. *
  2222. *   NAME
  2223. *    CmdFlush --
  2224. *
  2225. *   SYNOPSIS
  2226. *    success = CmdFlush()
  2227. *
  2228. *    BOOL CmdFlush();
  2229. *
  2230. *   FUNCTION
  2231. *
  2232. *   INPUTS
  2233. *
  2234. *   RESULT
  2235. *
  2236. *   EXAMPLE
  2237. *
  2238. *   NOTES
  2239. *
  2240. *   BUGS
  2241. *
  2242. *   SEE ALSO
  2243. *
  2244. ****************************************************************************
  2245. *
  2246. */
  2247.  
  2248. BOOL CmdFlush()
  2249. {
  2250.    return TRUE;
  2251. }
  2252.  
  2253.  
  2254.  
  2255. /****i* ram.handler/CmdAddNotify *******************************************
  2256. *
  2257. *   NAME
  2258. *    CmdAddNotify --
  2259. *
  2260. *   SYNOPSIS
  2261. *    success = CmdAddNotify(handler,request)
  2262. *
  2263. *    BOOL CmdAddNotify(struct Handler *,struct NotifyRequest *);
  2264. *
  2265. *   FUNCTION
  2266. *
  2267. *   INPUTS
  2268. *
  2269. *   RESULT
  2270. *
  2271. *   EXAMPLE
  2272. *
  2273. *   NOTES
  2274. *
  2275. *   BUGS
  2276. *
  2277. *   SEE ALSO
  2278. *
  2279. ****************************************************************************
  2280. *
  2281. */
  2282.  
  2283. BOOL CmdAddNotify(struct Handler *handler,struct NotifyRequest *request)
  2284. {
  2285.    LONG error;
  2286.    struct Notification *notification;
  2287.    struct Object *object;
  2288.  
  2289.    error=0;
  2290.    notification=AllocMem(sizeof(struct Notification),MEMF_CLEAR);
  2291.    if(notification==NULL)
  2292.       error=IoErr();
  2293.  
  2294.    if(error==0)
  2295.    {
  2296.       AddTail((APTR)&handler->notifications,(APTR)notification);
  2297.  
  2298.       notification->request=request;
  2299.       request->nr_Flags&=~NRF_MAGIC;
  2300.  
  2301.       object=GetObject(handler,NULL,request->nr_FullName,NULL);
  2302.       notification->object=object;
  2303.  
  2304.       if((object!=NULL)&&(request->nr_Flags&NRF_NOTIFY_INITIAL))
  2305.          Notify(handler,notification);
  2306.    }
  2307.  
  2308.    /* Return success indicator */
  2309.  
  2310.    SetIoErr(error);
  2311.    return error==0;
  2312. }
  2313.  
  2314.  
  2315.  
  2316. /****i* ram.handler/CmdRemoveNotify ****************************************
  2317. *
  2318. *   NAME
  2319. *    CmdRemoveNotify --
  2320. *
  2321. *   SYNOPSIS
  2322. *    success = CmdRemoveNotify(handler,request)
  2323. *
  2324. *    BOOL CmdRemoveNotify(struct Handler *,struct NotifyRequest *);
  2325. *
  2326. *   FUNCTION
  2327. *
  2328. *   INPUTS
  2329. *
  2330. *   RESULT
  2331. *
  2332. *   EXAMPLE
  2333. *
  2334. *   NOTES
  2335. *
  2336. *   BUGS
  2337. *
  2338. *   SEE ALSO
  2339. *
  2340. ****************************************************************************
  2341. *
  2342. */
  2343.  
  2344. BOOL CmdRemoveNotify(struct Handler *handler,struct NotifyRequest *request)
  2345. {
  2346.    struct Notification *notification;
  2347.  
  2348.    notification=FindNotification(handler,request);
  2349.    if(notification!=NULL)
  2350.    {
  2351.       Remove((APTR)notification);
  2352.       FreeMem(notification,sizeof(struct Notification));
  2353.  
  2354.    }
  2355.  
  2356.    return TRUE;
  2357. }
  2358.  
  2359.  
  2360.  
  2361.